<script setup>
import { hiprint, defaultElementTypeProvider } from 'vue-plugin-hiprint'
import { GetDetailsAPI, GetConfigAPI, configContentAPI } from '@/api/system/printConfig'
// import { callPrinter } from 'call-printer'
// 预览
import printPreview from './view.vue'
import printInitConfig from './printConfig.json'
import { elementData, provider } from './element.js'
const { proxy } = getCurrentInstance()

const route = useRoute()
const router = useRouter()

const emit = defineEmits()
const props = defineProps({
  templateData: {
    type: Object,
    default: () => {}
  },
  elementData: {
    type: Array,
    default: () => []
  }
})

const elementList = ref([])
const toolList = ref([])
function Provider(options) {
  var addElementTypes = function (context) {
    // 移除 旧的 defaultModule "元素"类型, 以避免重复
    context.removePrintElementTypes('defaultModule')
    // 添加 defaultModule "元素"类型
    context.addPrintElementTypes('defaultModule', [
      // PrintElementTypeGroup 分组
      //如果使用 hiprint.PrintElementTypeManager.build('.hiprintEpContainer2', "defaultModule") //这里会渲染这个 "常规" 分组名称
      new hiprint.PrintElementTypeGroup('常规', props.elementData),
      new hiprint.PrintElementTypeGroup('辅助', [
        {
          tid: 'defaultModule.hline',
          title: '横线',
          type: 'hline'
        }
      ])
    ])
  }

  return {
    addElementTypes: addElementTypes
  }
}

// 面板 对象
const hiprintTemplate = ref()

// 预览实力
const preViewRef = ref(null)
const group = ref()
//  面板配置项
const templateConfig = reactive({
  zoom: 1,
  fontSize: '', // 文字大小
  horizontal: '', // 水平间距
  perpendicular: '', // 垂直间距
  title: '测试标题',
  width: 145, // 毫米 打印纸质宽度 number
  height: 99, // 毫米 打印纸质宽度 number
  data: [],
  // 基本纸张大小
  paperTypes: {
    label: {
      width: 150,
      height: 100
    },
    A3: {
      width: 420,
      height: 296.6
    },
    A4: {
      width: 210,
      height: 296.6
    },
    A5: {
      width: 210,
      height: 147.6
    },
    B3: {
      width: 500,
      height: 352.6
    },
    B4: {
      width: 250,
      height: 352.6
    },
    B5: {
      width: 250,
      height: 175.6
    }
  }
})

// hiprint
const hiprintForm = reactive({
  jsonOut: '' // 导出json数据
})
const loading = ref(false)

/**
 * 进入页面强制刷新
 */
onMounted(() => {
  // if (sessionStorage.getItem('print', 1) == '1') {
  //   sessionStorage.setItem('print', 2)
  //   location.reload()
  // }
})

/**
 * 构建设计器
 * 注意: 必须要在 onMounted 中去构建
 * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
 * 初始化
 */
const initPrint = data => {
  hiprint.init({
    providers: [provider([...data.arr, ...data.tool])]
  })
  // 还原配置
  hiprint.setConfig()
  // 替换配置
  hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
  $('#PrintElementOptionSetting').empty() // 先清空, 避免重复构建
  hiprintTemplate.value = new hiprint.PrintTemplate({
    template: templateConfig.data,
    // fields: [{ field: '', text: '' }],
    settingContainer: '#PrintElementOptionSetting', // 元素参数容器
    paginationContainer: '.hiprint-printPagination',
    dataMode: 1, // 1:getJson 其他：getJsonTid 默认1
    history: true, // 是否需要 撤销重做功能

    getSelectEls: function (data) {
      // console.log(data)
    },

    onDataChanged: (type, json) => {
      // console.log(type) // 新增、移动、删除、修改(参数调整)、大小、旋转
      // console.log(json.panels[0].printElements) // 返回 template
      //
    },
    onUpdateError: e => {
      // console.log(e)
    }
  })
  // 构建 并填充到 容器中
  hiprintTemplate.value.design('#hiprint-printTemplate', { axisEnabled: true })
  hiprint.hiwebSocket.setHost(import.meta.env.VITE_APP_BASE_PRINT)
}

/**
 * 获取打印接口
 */
const initTemplate = async () => {
  try {
    loading.value = true
    const res = await GetConfigAPI(route.query.id)
    // 如果有 用数据库 否则初始模板

    templateConfig.data = res.msg ? JSON.parse(res.msg) : printInitConfig
    const resp = await GetDetailsAPI(route.query.printCorrelation)
    const elementArr = elementData(resp.data)
    elementList.value = elementArr.arr
    toolList.value = elementArr.tool
    const config = templateConfig.data.panels[0]
    console.log(config, 'config')

    templateConfig.height = config.height
    templateConfig.width = config.width
    templateConfig.typeDict = `宽${templateConfig.width}mm 高${templateConfig.height}mm`
    nextTick(() => {
      initPrint(elementData(resp.data))
    })
  } catch (error) {
  } finally {
    loading.value = false
  }
}
initTemplate()

// 获取元素
const getSelectEls = () => {
  const el = hiprintTemplate.value.getSelectEls()
  // console.log(el)
}

// 左对齐
const setElsAlign = e => {
  hiprintTemplate.value.setElsAlign(e)
}
/**
 * true为水平 false为垂直
 */
const setElsSpace = num => {
  if (!num) return
  hiprintTemplate.value.setElsSpace(num ? num : templateConfig.horizontal, true)
}
// 垂直间距
const perpendicular = num => {
  if (!num) return
  hiprintTemplate.value.setElsSpace(num ? num : templateConfig.perpendicular, false)
}

// 修改文字大小
const updateFontSize = () => {
  if (!templateConfig.fontSize) return
  hiprintTemplate.value.updateOption('fontSize', templateConfig.fontSize)
}

// 确认修改
const subEdit = () => {
  setElsSpace()
  perpendicular()
  updateFontSize()
}
const updateFontWeight = () => {
  hiprintTemplate.value.updateOption('fontWeight', 'bolder')
}

const rotatePaper = () => {
  if (hiprintTemplate.value) {
    hiprintTemplate.value.rotatePaper()
  }
}

/**
 * 设置纸张大小
 * @param type [A3, A4, A5, B3, B4, B5, other]
 * @param value {width,height} mm
 */
const setPaper = value => {
  try {
    hiprintTemplate.value.zoom(templateConfig.zoom, false)
    if (value != 'zdy') {
      templateConfig.width = templateConfig.paperTypes[value].width
      templateConfig.height = templateConfig.paperTypes[value].height
    }
    templateConfig.typeDict =
      value != 'zdy'
        ? `${value} 宽${templateConfig.width}mm 高${templateConfig.height}mm`
        : `自定义 宽${templateConfig.width}mm 高${templateConfig.height}mm`
    templateConfig.type = value
    hiprintTemplate.value.setPaper(templateConfig.width, templateConfig.height)
  } catch (error) {
    new Error(error)
    proxy.warningMsg(`操作失败: ${error}`)
  }
}
// JSON导出
const exportJson = async () => {
  // console.log(hiprintTemplate.value)
  if (hiprintTemplate.value) {
    hiprintForm.jsonOut = JSON.stringify(hiprintTemplate.value.getJson() || {})
  }
  // 配置修改保存
  proxy.$modal.loading('请稍候...')
  try {
    await configContentAPI({
      printId: route.query.id,
      statsJson: JSON.stringify(hiprintTemplate.value.getJson() || {})
    })
    proxy.successMsg('配置成功')
  } catch (err) {
    console.log(err)
  } finally {
    proxy.$modal.closeLoading()
  }
  emit('exportJson', JSON.stringify(hiprintTemplate.value.getJson() || {}))

  // console.log(hiprintForm.jsonOut)
}

/**
 * 关闭当前页面
 */
const backTo = async () => {
  const result = await proxy.MessageBox('关闭当前页面，数据会销毁，请确认数据已保存')
  if (!result) return
  router.push('/system/printConfig')
}

// 清空
const clearPaper = async () => {
  const isif = await proxy.MessageBox('确定要清空吗？')
  if (!isif) return
  try {
    hiprintTemplate.value.clear()
  } catch (error) {
    this.$message.error(`操作失败: ${error}`)
  }
}

// 打印
const print = async () => {
  await hiprintTemplate.value.getPrinterList()
  // 判断是否已成功连接
  if (!hiprint.hiwebSocket.opened) {
    // 重新连接客户端  当然你可以去连接局域网内的客户端
    hiprint.hiwebSocket.setHost(import.meta.env.VITE_APP_BASE_PRINT)
    // hiprint.hiwebSocket.host = 'http://192.168.0.75:17521'

    proxy.warningMsg('打印机未连接，正在尝试连接')
    return
  }
  proxy.$modal.loading('打印中，请稍候...')
  // proxy.$modal.loading('打印中,请稍候...')
  hiprintTemplate.value.on('printSuccess', function (data) {
    setTimeout(() => {
      proxy.$modal.closeLoading()
      emit('printYes')
      proxy.successMsg('打印机操作完成')
    }, 1000)
  })
  hiprintTemplate.value.print2(
    {
      detailList: [{ materialCode: '111', materialName: '我是测试表格' }],
      qrcode: 'WT-10000',
      barcode: 'WT10001',
      productionNumber: 'WT10001',
      materialCode: 'YL-10000',
      materialName: '我是名称',
      rollingDiameter: '10克',
      grossWeight: '1克',
      grawWeight: '1克',
      joint: '1',
      defect: '1',
      materialRatio: 'YL-13B-1',
      materialNet: 'A',
      materialNetType: 'B',
      createMan: '胡伟'
    },
    {
      printer: '',
      title: '普众联合-打印服务'
    },
    {
      callback: () => {
        // console.log('浏览器打印窗口已打开')
        proxy.$modal.closeLoading()
      }
    }
  )
  //   this.$message.error('客户端未连接,无法直接打印')
}

// 预览
const preView = () => {
  preViewRef.value.isShow(hiprintTemplate.value, {
    detailList: [
      { materialCode: '123', materialName: '我是测试表格1', num: '1' },
      { materialCode: '456', materialName: '我是测试表格2', num: '2' }
    ],
    totalCap: '100',
    qrcode: 'WT-10000',
    barcode: 'WT10001',
    productionNumber: 'WT10001',
    materialCode: 'YL-10000',
    materialName: '我是名称',
    rollingDiameter: '10克',
    grossWeight: '1克',
    grawWeight: '1克',
    joint: '1',
    defect: '1',
    materialRatio: 'YL-13B-1',
    materialNet: 'A',
    materialNet_type: 'B',
    createMan: '胡伟',

    // 二维码字段必须要有数据 否则预览不显示
    a: '111',
    b: '222'
  })
}
</script>

<template>
  <div class="app-container">
    <el-form>
      <el-row>
        <el-col :span="24" class="mb10">
          <el-button @click="setPaper('label')">标签</el-button>
          <!-- <el-button @click="setPaper('A3')">A3</el-button> -->
          <el-button @click="setPaper('A4')">A4</el-button>
          <!-- <el-button @click="setPaper('A5')">A5</el-button> -->
          <!-- <el-button @click="setPaper('B3')">B3</el-button> -->
          <!-- <el-button @click="setPaper('B4')">B4</el-button> -->
          <!-- <el-button @click="setPaper('B5')">B5</el-button> -->
          <el-popover placement="right" :width="400" trigger="click">
            <template #reference>
              <el-button type="primary">自定义宽高</el-button>
            </template>
            <el-form>
              <el-form-item label="宽">
                <el-input v-model="templateConfig.width" />
              </el-form-item>
              <el-form-item label="高">
                <el-input v-model="templateConfig.height" />
              </el-form-item>
              <el-form-item label="高">
                <el-button type="primary" @click="setPaper('zdy', templateConfig)">确认</el-button>
              </el-form-item>
            </el-form>
          </el-popover>
        </el-col>
      </el-row>
    </el-form>

    <div class="mt10">
      <el-button @click="updateFontWeight(true)">选中元素字体Bolder</el-button>
      <el-button @click="setElsSpace(true, 10)">水平间距10</el-button>
      <el-button @click="perpendicular(false, 10)">垂直间距10</el-button>
      <el-button @click="setElsAlign('left')">左对齐</el-button>
      <el-button @click="setElsAlign('vertical')">居中</el-button>
      <el-button @click="setElsAlign('right')">右对齐</el-button>
      <el-button @click="setElsAlign('top')">顶部对齐</el-button>
      <el-button @click="setElsAlign('horizontal')">垂直居中</el-button>
      <el-button @click="setElsAlign('bottom')">底部对齐</el-button>
      <el-button @click="setElsAlign('distributeHor')">横向分散</el-button>
      <el-button @click="setElsAlign('distributeVer')">纵向分散</el-button>
      <el-button type="warning" @click="backTo">关闭此页面</el-button>
      <el-button type="primary" @click="preView">预览</el-button>
      <el-button type="success" @click="print">打印</el-button>
      <el-button type="info" @click="clearPaper">清空</el-button>
      <el-button type="warning" @click="exportJson">保存</el-button>
    </div>

    <div :class="templateConfig.type == 'A3' || templateConfig.type == 'B3' ? '233' : 'flex'">
      <!-- 样式完全自定义 -->
      <el-card class="box-card element">
        <template #header>
          <div class="card-header">
            <div class="title">控件</div>
          </div>
        </template>
        <div>
          <h5>字段</h5>
          <div
            class="element-main"
            :class="{
              'element-main-233': templateConfig.type == 'A3' || templateConfig.type == 'B3'
            }"
          >
            <div class="ep-draggable-item" :tid="item.tid" v-for="(item, index) in elementList" :key="index">
              <i :class="`iconfont icon-${item.icon}`" />
              <div class="textClass">{{ item.title }}</div>
            </div>
          </div>
        </div>

        <!-- 工具类 -->
        <div>
          <h5>工具类</h5>
          <div class="element-main">
            <div class="ep-draggable-item" :tid="item.tid" v-for="(item, index) in toolList" :key="index">
              <i :class="`iconfont icon-${item.icon}`" />
              <div class="textClass">{{ item.title }}</div>
            </div>
          </div>
        </div>
      </el-card>
      <!-- 设计器的 容器 -->
      <el-card
        @click="getSelectEls"
        class="box-card main"
        v-loading="loading"
        :style="`width:${templateConfig.width + 10}mm;height:auto;min-width: ${templateConfig.width + 10}mm;`"
      >
        <div class="title">标签设计</div>
        <div id="hiprint-printTemplate" @click="getSelectEls"></div>
      </el-card>
      <!-- 基础属性 -->
      <el-card class="box-card toosKey">
        <div id="PrintElementOptionSetting"></div>
      </el-card>
    </div>
    <!-- 预览 -->
    <print-preview ref="preViewRef" />
  </div>
</template>
<style lang="scss" scoped>
.flex {
  width: 100%;
  display: flex;
  justify-content: center;
}
// .element {
//   min-width: 200px !important;
//   max-width: 320px !important;
// }
.element-main {
  display: flex;
  flex-wrap: wrap;
  min-width: 280px;
  max-width: 350px;
  overflow: auto;
  flex: 1;
}

.element-main-233 {
  min-width: 100%;
  max-width: 100%;
  width: 100%;
}

.main {
  padding: 10px 0;
  padding-top: 0;
  overflow: hidden;
  display: flex;
  justify-content: center;
  margin: 0 20px;

  .title {
    margin-bottom: 40px;
  }
}
.title {
  text-align: center;
}
.toosKey {
  height: 500px;
  overflow: auto;
  max-width: 398px;
  min-width: 398px;
}
.flex-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}
.ep-draggable-item {
  border: 1px solid #d7dae0;
  padding: 1px 5px;
  width: 4.3rem;
  height: 1.75rem;
  margin: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  .iconfont {
    font-size: 40px;
  }
  font-size: 12px;
  .textClass {
    text-align: center;
    width: 4.3rem;
    height: 1.75rem;
    line-height: 1.75rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
.rk ::v-deep .el-form-item {
  width: 180px !important;
  height: 10px !important;
}

.box {
  width: 280px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}
.ep-draggable-item {
  margin: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  .iconfont {
    font-size: 40px;
  }
  font-size: 12px;
}

// .app-container ::v-deep  {
//   display: none !important;
// }
.flex-items-center {
  justify-content: center;
}

.flex-between {
  display: flex;
  align-items: center;
}
.element-config {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  width: auto;
  max-width: 700px;
}
.width-config {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.flex-between {
  width: 500px;
}
</style>
